from .models import User, Token, ProductDetail, Shopcarts, Product, Coupon, CouponUse, Address, ProductAttribute, \
    OrderProduct, Order
from rest_framework.views import APIView
from rest_framework.viewsets import ModelViewSet
from rest_framework.response import Response
from utils import wx_auth, authentication, throttles, pagination
import uuid, datetime
from django.utils.timezone import now
from .serializer import ProductSerializer, ShopCarsSerializer, ProductListSerializer, CouponSerializer, AddressSerializer, ProductDetailSerializer, ProductAttributeSerializer

# TODO
"""
1.分页
"""


# 登录
class LoginView(APIView):
    def post(self, request):
        req_data = request.data
        # 获取传递的code
        code = req_data.get('code', '')
        # 判断是否有code
        if not code:
            return Response({'error': '没有获取到code'})
        try:
            # 获取openid
            auth_code = wx_auth.auth_code2Session(code)
            openid = auth_code.get('openid', '')
            # 判断是否是正确的openid
            if not openid:
                return Response({'error': '错误的code'})
            # 验证数据库是否存在该用户,判断其状态是否激活
            user_obj_false = User.objects.filter(user_uuid=openid, is_active=False).first()
            if user_obj_false:
                return Response({'error': '该用户已存在但未激活'})
            # 验证数据库是否存在该用户,不存在则创建
            user_obj = User.objects.filter(user_uuid=openid, is_active=True).first()
            token = uuid.uuid4()
            if not user_obj:
                # 创建用户，返回token
                user_obj_code = User.objects.create(user_js_code=code, user_uuid=auth_code.get('openid'))
                Token.objects.create(token=token, user=user_obj_code)
                return Response({'userID': user_obj_code.id, 'token': token})
            # 如果存在该用户，则更新token后返回
            try:
                Token.objects.filter(user=user_obj).update(token=token)
            except Exception as e:
                return Response({'error': '登录失败'})
            return Response({'userID': user_obj.id, 'token': token})
        except Exception as e:
            return Response({'error': '登录异常错误'})


# 商品分类列表
class PeoductTypeListView(APIView):
    def get(self, request):
        # 获取参数
        list_type = request.query_params.get('product_type', '')
        # 验证数据
        if not type:
            return Response({'error': '参数不能为空'})
        # try:
        # 查询数据并验证
        product_obj_list = Product.objects.filter(product_type=list_type, publish_status=True)
        if not product_obj_list:
            return Response({})
        # 分页
        page_obj = pagination.PageNumberSize()
        page_data = page_obj.paginate_queryset(product_obj_list, request)
        # 序列化
        ser_obj = ProductListSerializer(page_data, many=True)
        # 调用分页的返回值，返回总数、上一页、下一页
        return page_obj.get_paginated_response(ser_obj.data)
    # except Exception as e:
    #     print(e)
    #     return Response({'error': '服务器内部错误'})


# 商品详情
class ProductDetailView(ModelViewSet):
    queryset = ProductDetail.objects.all()
    serializer_class = ProductDetailSerializer


# 购物车
class ShopCarsView(ModelViewSet):
    authentication_classes = [authentication.LoginAuth]
    queryset = Shopcarts.objects.all()
    serializer_class = ShopCarsSerializer

    # 重写方法,查询列表
    def retrieve(self, request, *args, **kwargs):
        # 获取请求用户id
        user_id = request.query_params.get('userID', '')
        # 验证id
        if not user_id:
            return Response({'error': 'userID不能为空'})
        if not user_id.isdigit():
            return Response({'error': 'userID必须为数字'})
        try:
            # 查询，并判断是否有数据
            shopcars_obj = Shopcarts.objects.filter(user_id=user_id)
            if not shopcars_obj:
                return Response({'error': '无此对象'})
            # 返回序列化结果
            ser_obj = ShopCarsSerializer(shopcars_obj, many=True)
            return Response(ser_obj.data)
        except Exception as e:
            return Response({'error': '服务器内部错误'})


# 优惠券查询
class CouponFindView(APIView):
    def get(self, request):
        # 传参：userID 返回值：该用户拥有的优惠券
        userId = request.query_params.get('userID', '')
        status = request.query_params.get('status', '')
        # 验证参数
        # 验证优惠券类型数据
        try:
            status = int(status)
            if status not in [1, 2, 3]:
                return Response({'error': '参数值错误, 不是有效类型id'})
        except:
            return Response({'error': '参数值错误, 不是有效类型id'})
        # 验证用户id
        if not userId or not userId.isdigit():
            return Response({'error': '参数值错误'})
        try:
            coupon_obj = CouponUse.objects.filter(user=userId)
            if userId and status:
                coupon_obj = CouponUse.objects.filter(user=userId, status=status)
            if not coupon_obj:
                return Response([])
            ser_obj = CouponSerializer(coupon_obj, many=True)
            return Response(ser_obj.data)
        except Exception as e:
            print(e)
            return Response({'error': '服务器内部错误'})


# 地址接口
class AddressView(APIView):
    def get(self, request):
        userID = request.query_params.get('userID', '')
        # is_default = request.query_params.get('is_default', '')
        # 验证数据
        if not userID or not userID.isdigit():
            return Response({'error': '不是有效用户id'})
        # 查询数据
        addr_obj = Address.objects.filter(user_id=userID, is_active=True)
        # 验证是否有数据
        if not addr_obj:
            return Response([])
        try:
            ser_obj = AddressSerializer(addr_obj, many=True)
            return Response(ser_obj.data)
        except Exception as e:
            return Response({'error': '服务器内部错误'})

    def post(self, request):
        req_data = request.data
        # 获取参数
        is_default = req_data.get('is_default', '')
        addr_phone = req_data.get('addr_phone', '')
        # 验证数据addr_phone
        if not addr_phone.isdigit() or len(addr_phone) != 11:
            return Response({'error': 'addr_phone不合法'})
        # 验证id
        userID = req_data.get('user', '')
        if not userID:
            return Response({'error': '未携带id'})
        user_obj = User.objects.filter(id=userID).first()
        if not user_obj:
            return Response({'error': '用户不存在'})
        try:
            # 修改该用户地址默认状态
            if is_default:
                user_obj.address_set.update(is_default=False)
            # 增加一条数据
            ser_obj = AddressSerializer(data=req_data)
            # 验证数据
            if ser_obj.is_valid():
                ser_obj.save()
                return Response({'status': True})
            return Response({'error': '保存失败'})
        except Exception as e:
            return Response({'error': '服务器内部出错'})

    # 删除数据
    def delete(self, request):
        # 获取参数
        user = request.query_params.get('user', '')
        address_id = request.query_params.get('address_id', '')
        # 验证数据
        if not user or not address_id or not str(user).isdigit() or not str(address_id).isdigit():
            return Response({'error': '数据不合法'})
        try:
            # 修改状态
            adr = Address.objects.filter(user_id=user, id=address_id, is_active=True).update(is_active=False)
            if adr == 1:
                return Response({'status': 'True'})
            return Response({'status': 'True'})
        except:
            return Response({'error': '服务器内部错误'})


# 测试类
class TestView(APIView):
    authentication_classes = [authentication.LoginAuth]
    # throttle_classes = [throttles.Throttles]

    def post(self, request):
        shop_obj = Shopcarts.objects.create(user_id=10, product_id=1, product_attribute_id=1, product_number=4)
        return Response('shop_obj')

    def get(self, request):
        pro_detail_obj = ProductDetail.objects.filter(id=4).first()
        print(dir(pro_detail_obj))

        # pro_attr_list = pro_detail_obj.productAttribute_set
        return Response('ok')


# 下单
class SettlementView(APIView):
    def post(self, request):
        '''
        需要传递的参数
        1. product_id                  商品id
        2. product_attribute_id        商品属性id
        3. product_number           商品数量
        4. couponUse_id             用户的优惠券id(可不传）
        5. address_id                  地址id
        6. userId                      用户id
        '''
        try:
            now_time_str = datetime.datetime.now().strftime('%Y%m%d%f')
            print(now_time_str)
            total_price = 0
            amount_price = 0
            district_money = 0
            # 获取参数
            ret_data = request.data
            userID = ret_data.get('userID', '')
            product_id = ret_data.get('product_id', '')
            product_attribute_id = ret_data.get('product_attribute_id', '')
            product_number = ret_data.get('product_number', '')
            address_id = ret_data.get('address_id', '')
            couponUse_id = ret_data.get('couponUse_id', '')
        except Exception as e:
            print(e)
            return Response('eeee')

        try:

            address_obj = Address.objects.filter(id=address_id).first()
            if not address_obj:
                return Response('addr--1')

            # 验证数据
            # 获取属性对象
            pro_atr_obj = ProductAttribute.objects.filter(id=product_attribute_id).first()
            if not pro_atr_obj:
                return Response('1')

            # 比较购买数量与库存数量
            if product_number > int(pro_atr_obj.stock_quantity):
                return Response('2')

            # 计算订单金额
            total_price += int(product_number) * int(pro_atr_obj.price)

            # 获取优惠券对象
            couponUse_obj = CouponUse.objects.filter(id=couponUse_id).first()
            coupon_obj = couponUse_obj.coupon
            if couponUse_obj.status in [2, 3]:
                return Response('coupon--1')
            # 优惠券生效时间
            effective_time = coupon_obj.effective_time
            # 优惠券失效时间
            invalid_time = coupon_obj.invalid_time
            # 判断用户优惠券是否可用,并计算优惠金额
            if now() < effective_time or now() > invalid_time:
                pass
            elif coupon_obj.coupon_type == 2:   # 判断优惠券类型 2 通用优惠券  1 满减优惠券
                total_price -= int(coupon_obj.amount)
                district_money = coupon_obj.amount
            elif coupon_obj.coupon_type == 1:
                if int(coupon_obj.min_amount) < total_price:
                    total_price -= int(coupon_obj.amount)
                    district_money = coupon_obj.amount

            # user = User.objects.filter(id=userID).first()
            order_data = {
                'user_id': userID,
                'order_numbering': now_time_str,
                'order_price': total_price,
                'order_status': 2,
                'address': address_obj,
                'district_money': district_money
            }
            # 创建订单
            order_obj = Order.objects.create(**order_data)

            order_product_data = {
                'product_id': product_id,
                'product_attribute_id': product_attribute_id,
                'product_number': product_number,
                'order_id': order_obj.id
            }
            order_product_obj = OrderProduct.objects.create(**order_product_data)

        except Exception as e:
            print(e)
            return Response('E1')







        # try:
        #     # 获取对象
        #     pro_detail_obj = ProductDetail.objects.filter(id=product_id).first()
        #     pro_atr_obj = ProductAttribute.objects.filter(id=product_attribute_id).first()
        #     # 验证是否存在该对象
        #     if not pro_detail_obj or not pro_atr_obj:
        #         return Response({'error': '没有要结算的对象'})
        # except Exception as e:
        #     print(e)
        #     return Response({'error': e})
        # # 判断传递商品id与属性id是否匹配
        # attr_proDetail_id = pro_atr_obj.productDetail.id
        # if not (pro_detail_obj.id == attr_proDetail_id):
        #     return Response({'error': '商品与属性不符合'})
        #



        return Response('ok')


# 增加商品
class AddProduct(APIView):
    def post(self, request):
        try:
            # 获取post请求的参数
            req_data = request.data

            product_data = req_data['product_data']
            productDetail_data = req_data['productDetail_data']
            productAttribute_data = req_data['productAttribute_data']

            # product_data = {
            #     'product_id': '5865844546',
            #     'product_name': 1,
            #     'product_type': 1,
            #     'show_img': 'oasid',
            #     'descript': 'asgs'
            # }
            # productDetail_data = {
            #     'product_swiper_img': '4532',
            #     'product_title': '453',
            #     'product_title_description': '453',
            #     'product_detail': '345',
            #     'product_detail_img': '453'
            # }
            # productAttribute_data = [{
            #     'attribute': '345',
            #     'characteristic': '453',
            #     'attribute_img': '453',
            #     'stock_quantity': '11',
            #     'price': '783'
            # }, {
            #     'attribute': '783',
            #     'characteristic': '783',
            #     'attribute_img': '783',
            #     'stock_quantity': '3783',
            #     'price': '783'
            # }]
            # 序列化
            ser_obj_pro = ProductSerializer(data=product_data)
            if ser_obj_pro.is_valid():
                ser_obj_pro.save()
            else:
                return Response({'error': str(ser_obj_pro.errors)})

            # 为下面要插入的表查询id
            product_id = Product.objects.filter(product_id=product_data['product_id']).first().id
            productDetail_data['product'] = product_id
            ser_obj_detail = ProductDetailSerializer(data=productDetail_data)
            if ser_obj_detail.is_valid():
                ser_obj_detail.save()
            else:
                # 如果出错，撤销之前的插入
                Product.objects.filter(id=product_id).delete()
                return Response({'error': str(ser_obj_detail.errors)})
            # 获取id
            productDetail_id = ProductDetail.objects.filter(product_id=product_id).first().id
            # 将id添加到数据中
            for item in productAttribute_data:
                item['productDetail'] = productDetail_id
                ser_obj_attr = ProductAttributeSerializer(data=item)
                if ser_obj_attr.is_valid():
                    ser_obj_attr.save()
                else:
                    # 如果出错，撤销之前的插入
                    ret = ProductAttribute.objects.filter(productDetail_id=productDetail_id).delete()
                    ret = ProductDetail.objects.filter(product_id=product_id).delete()
                    ret = Product.objects.filter(id=product_id).delete()
                    return Response({'error': str(ser_obj_attr.errors)})
            return Response({'status': 'ok'})
        except:
            return Response({'error': '服务器内部错误'})
